<template>
    <div class="mpvue-picker">
        <view @click.stop.prevent="show" class="mpvue-picker__show azm-ellipsis">
            <block v-if="isShowLabel && showLabel">
                <text>{{showLabel}}</text>
            </block>
            <block v-else>
                <text class="input-placeholder">{{placeholder}}</text>
            </block>
        </view>

        <div :class="{'pickerMask':showPicker}" @click.stop.prevent="maskClick" catchtouchmove="true"></div>
        <div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
            <div class="mpvue-picker__hd" catchtouchmove="true">
                <div class="mpvue-picker__action" @click.stop.prevent="pickerCancel">取消</div>
                <div class="mpvue-picker__action" :style="{color:themeColor}" @click.stop.prevent="pickerConfirm">确定
                </div>
            </div>
            <picker-view indicator-style="height: 40px;" class="mpvue-picker-view"
                         :value="pickerValue" @change.stop.prevent="pickerChange">
                <picker-view-column>
                    <div class="picker-item" v-for="(item,index) in provinceDataList"
                         :key="index">{{item.label}}
                    </div>
                </picker-view-column>
                <picker-view-column>
                    <div class="picker-item" v-for="(item,index) in cityDataList"
                         :key="index">{{item.label}}
                    </div>
                </picker-view-column>
                <picker-view-column>
                    <div class="picker-item" v-for="(item,index) in areaDataList"
                         :key="index">{{item.label}}
                    </div>
                </picker-view-column>
            </picker-view>
        </div>
    </div>
</template>

<script>
    import { debounce } from '@u/lodash/throttle'

    let CityData = [];
    let PROVINCE = [];
    let CITY = [];
    let SAVE_VALUE = [];

    let OPTS = {};
    export default {
        name: 'tl-city-picker',
        data () {
            return {
                showLabel: '',
                pickerValue: [],
                PickerData: [],
                provinceDataList: [],
                cityDataList: [],
                areaDataList: [],
                /* 是否显示控件 */
                showPicker: false,
                isShowLabel: false
            };
        },
        created () {

        },
        props: {
            value: {
                type: Array,
                default () {
                    return []
                }
            },
            // 默认显示
            showAttr: {
                type: String,
                default: 'label'
            },
            /* 主题色 */
            themeColor: String,
            placeholder: String,
            props: {
                type: Object,
                default () {
                    return {
                        value: 'value',
                        label: 'label',
                        children: 'children',
                    };
                }
            }
        },
        watch: {
            pickerValue (n, o) {
                if (n.toString() === o.toString()) return;
                this.changPickerValue(n, o);
            },
            value (n) {
                this.isShowLabel = !this.$util.jude.isEmptyArray(n);
            },
            showPicker (n) {
                if (n === false) {
                    OPTS = {}
                }
            }
        },
        methods: {
            getArrayValue (arr) {
                let vm = this;
                if (!Array.isArray(arr)) return [];
                const {value = 'value', label = 'label'} = vm.$util.jude.isEmptyObject(vm.props) ? {} : vm.props;
                return arr.map(v => {
                    if (v[value] && v[label]) {
                        return {
                            [value]: v[value],
                            [label]: v[label]
                        }
                    }
                })
            },
            async handPickValueDefault () {
                let vm = this;
                const {value = 'value', label = 'label', children = 'children'} = vm.$util.jude.isEmptyObject(vm.props) ? {} : vm.props;
                const cityData = vm.$Storage.getStorageSync('cityData');
                if (!this.$util.jude.isEmptyObject(cityData, true)) return Promise.resolve(cityData);
                const result = await vm.$ajax.Common.getAdcode();
                if (result && result.code === 0 && result.data && !vm.$util.jude.isEmptyArray(result.data.items)) {
                    CityData = JSON.parse(JSON.stringify(result.data.items)
                        .replace(/(code)/ig, value)
                        .replace(/(name)/ig, label)
                        .replace(/(cityList|regionList|list)/ig, children));
                    vm.$Storage.setStorageSync('cityData', CityData, '1d')
                } else {
                    return Promise.reject();
                }
                return Promise.resolve(CityData)
            },
            async init () {
                const vm = this;
                const [PROVINCE_ID, CITY_ID, AREA_ID] = Array.isArray(vm.value) ? vm.value : [];
                CityData = await this.handPickValueDefault();
                const {value = 'value', label = 'label', children = 'children'} = vm.$util.jude.isEmptyObject(vm.props) ? {} : vm.props;
                let province_id, city_id, area_id, province, city, area;

                const Province = [...CityData];
                if (Array.isArray(Province) && Province.length > 0) {
                    province = Province.find(v => +v[value] === +PROVINCE_ID);
                    if (!province) province = Province[0];
                    vm.provinceDataList = vm.getArrayValue(Province);
                    vm.PickerData[0] = {value: province[value], label: province[label]};
                    province_id = province[value];
                }

                const City = [...province[children]];
                if (Array.isArray(City) && City.length > 0) {
                    city = City.find(v => +v[value] === +CITY_ID);
                    if (!city) city = City[0];
                    vm.cityDataList = vm.getArrayValue(City);
                    vm.PickerData[1] = {value: city[value], label: city[label]};
                    city_id = city[value];
                }

                const Area = [...city[children]];
                if (Array.isArray(Area) && Area.length > 0) {
                    area = Area.find(v => +v[value] === +AREA_ID);
                    if (!area) area = Area[0];
                    vm.areaDataList = vm.getArrayValue(Area);
                    vm.PickerData[2] = {value: area[value], label: area[label]};
                    area_id = area[value];
                }

                if (this.isShowLabel) {
                    const pickerProvince = vm.provinceDataList.findIndex(v => +v[value] === +province_id);
                    const pickerCity = vm.cityDataList.findIndex(v => +v[value] === +city_id);
                    const pickerArea = vm.areaDataList.findIndex(v => +v[value] === +area_id);
                    vm.pickerValue = [
                        pickerProvince > -1 ? pickerProvince : 0,
                        pickerCity > -1 ? pickerCity : 0,
                        pickerArea > -1 ? pickerArea : 0
                    ];
                    vm.pickerConfirm(true)
                } else {
                    vm.pickerValue = [0, 0, 0];
                }
            },
            modifyCity (index = 0, ParentData = []) {
                let vm = this;
                const {value = 'value', label = 'label', children = 'children'} = vm.$util.jude.isEmptyObject(vm.props) ? {} : vm.props;
                const City = [...ParentData];
                if (Array.isArray(City) && City.length > 0) {
                    vm.cityDataList = vm.getArrayValue(City);
                    this.modifyArea(0, City[0][children]);
                } else {
                    vm.cityDataList = []
                    vm.areaDataList = []
                }
                vm.pickerValue.splice(1, 1, 0);
            },
            modifyArea (index = 0, ParentData = []) {
                let vm = this;
                const Area = [...ParentData];
                if (Array.isArray(Area) && Area.length > 0) {
                    vm.areaDataList = vm.getArrayValue(Area);
                } else {
                    vm.areaDataList = []
                }
                vm.pickerValue.splice(2, 1, 0);
            },
            changPickerValue: debounce(function (n, o) {
                const vm = this;
                const [PROVINCE_INDEX, CITY_INDEX, AREA_INDEX] = Array.isArray(n) ? n : [];
                const [OLD_PROVINCE_INDEX, OLD_CITY_INDEX, OLD_AREA_INDEX] = Array.isArray(o) ? o : [];
                const {children = 'children'} = vm.$util.jude.isEmptyObject(vm.props) ? {} : vm.props;
                if (CityData.length === 0) return;
                PROVINCE = CityData.length > PROVINCE_INDEX && PROVINCE_INDEX > -1 ? CityData[PROVINCE_INDEX] : CityData[0];
                if (PROVINCE && PROVINCE[children]) {
                    CITY = PROVINCE[children][CITY_INDEX]
                }
                if (PROVINCE_INDEX !== OLD_PROVINCE_INDEX) {
                    this.modifyCity(CITY_INDEX, PROVINCE[children]);
                } else if (CITY_INDEX !== OLD_CITY_INDEX) {
                    this.modifyArea(AREA_INDEX, CITY[children]);
                }
                this._$emit('onChange');
            }, 50),
            async show ({value, success, fail} = {}) {
                let vm = this;
                await this.init();
                setTimeout(() => {
                    vm.showPicker = true;
                    vm.init();
                }, 0);
                OPTS = {success, fail};
            },
            maskClick () {
                this.pickerCancel();
            },
            pickerCancel () {
                this.showPicker = false;
                OPTS && typeof OPTS.fail === "function" && OPTS.fail();
                this._$emit('onCancel');
            },
            pickerConfirm (bol) {
                const pickObj = this._getData();
                this.$emit('input', pickObj.value);
                this.$nextTick(function () {
                    this.showLabel = pickObj.label;
                });
                console.log(pickObj);
                if (bol !== true) {
                    this.showPicker = false;
                    OPTS && typeof OPTS.success === "function" && OPTS.success(pickObj);
                    this.$emit('onConfirm', pickObj);
                }
            },
            showPickerView () {
                this.showPicker = true;
            },

            pickerChange (e) {
                this.pickerValue = [...e.mp.detail.value];
            },

            _$emit (emitName) {
                let vm = this;
                this.$emit(emitName, this._getData());
            },
            _getData () {
                let vm = this;
                let pickerValue = vm.pickerValue;
                let province = vm.provinceDataList.find((value, index) =>
                    pickerValue[0] > -1 ? pickerValue[0] === index : true
                );
                let city = vm.cityDataList.find((value, index) =>
                    pickerValue[1] > -1 ? pickerValue[1] === index : true
                );
                let area = vm.areaDataList.find((value, index) =>
                    pickerValue[2] > -1 ? pickerValue[2] === index : true
                );
                const {value = 'value', label = 'label', children = 'children'} = vm.$util.jude.isEmptyObject(vm.props) ? {} : vm.props;
                const pickObj = {
                    data: [province, city, area],
                    cityCode: area[value] || city[value] || province[value]
                };
                pickObj.label = pickObj.data.map(v => v[label]).join('-');
                pickObj.value = pickObj.data.map(v => v[value]);
                return pickObj;
            },
        }
    };
</script>

<style lang="scss">
    .mpvue-picker {
        position: relative;
        width: 100%;
    }

    .mpvue-picker__show {
        position: relative;
        width: 100%;
        font-size: 15*2upx;

        .mpvue-picker__show__text {
            color: #CCCCCC;
        }
    }

    .pickerMask {
        position: fixed;
        z-index: 1000;
        top: 0;
        right: 0;
        left: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.6);
    }

    .mpvue-picker-content {
        position: fixed;
        bottom: 0;
        left: 0;
        width: 100%;
        transition: all 0.3s ease;
        transform: translateY(100%);
        z-index: 3000;
    }


    .mpvue-picker-view-show {
        transform: translateY(0);
    }

    .mpvue-picker__hd {
        display: flex;
        padding: 9px 15px;
        background-color: #fff;
        position: relative;
        text-align: center;
        font-size: 17px;
    }

    .mpvue-picker__hd:after {
        content: ' ';
        position: absolute;
        left: 0;
        bottom: 0;
        right: 0;
        height: 1px;
        border-bottom: 1px solid #e5e5e5;
        color: #e5e5e5;
        transform-origin: 0 100%;
        transform: scaleY(0.5);
    }

    .mpvue-picker__action {
        display: block;
        flex: 1;
        color: #1aad19;
    }

    .mpvue-picker__action:first-child {
        text-align: left;
        color: #888;
    }

    .mpvue-picker__action:last-child {
        text-align: right;
    }

    .picker-item {
        text-align: center;
        line-height: 40px;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 16px;
    }

    .mpvue-picker-view {
        position: relative;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 238px;
        background-color: rgba(255, 255, 255, 1);
    }
</style>
